<script setup lang="ts">
import type { SimEngineBaseInfo } from "@/common/apis/engine-library/type"
import type { UploadType } from "@@/constants/other-keys"
import type { FormInstance, FormRules, UploadUserFile } from "element-plus"
import { createSimEngineDataApi, getSimEngineInfoApi, getSimEngineOSOptionsApi, updateSimEngineDataApi } from "@/common/apis/engine-library"
import UploadFolder from "@@/components/UploadFolder/index.vue"
import { FormTypeEnum } from "@@/constants/other-keys"
import { filesToZip } from "@@/utils/fileUtils"
import { ElMessage, ElMessageBox } from "element-plus"
import { cloneDeep, isEqual } from "lodash-es"
import { computed, ref, watch } from "vue"

interface Props {
  id: string | undefined
  dialogType: FormTypeEnum
  visible: boolean
}

const props = withDefaults(defineProps<Props>(), {
  dialogType: FormTypeEnum.VIEW
})
const emit = defineEmits(["closeDialog"])
const osOptions = ref<string[]>([])
const DEFAULT_FORM_DATA: SimEngineBaseInfo = {
  sim_engine_id: undefined,
  sim_engine_name: "",
  sim_engine_version: "1.0",
  sim_engine_files: "",
  sim_engine_os: [],
  describe: "",
  environment_variables: "",
  extension_parameters: "",
  main_file: ""
}
const dialogVisible = ref<boolean>(false)
const formRef = ref<FormInstance | null>(null)
const formData = ref<SimEngineBaseInfo>(cloneDeep(DEFAULT_FORM_DATA))
const formRules: FormRules<SimEngineBaseInfo> = {
  sim_engine_name: [{ required: true, trigger: "blur", message: "请输入引擎名称" }],
  sim_engine_version: [{ required: true, trigger: "blur", message: "请输入引擎版本" }],
  sim_engine_files: [{ required: true, trigger: "change", message: "选择文件" }],
  sim_engine_os: [{ required: true, trigger: "change", message: "请选择支持操作系统" }],
  main_file: [{ required: true, trigger: "change", message: "请输入主文件名称" }]
}
const fileList = ref<UploadUserFile[]>([])
const loading = ref<boolean>(false)
const detailLoading = ref<boolean>(false)
const uploadType = ref<UploadType>()
const isEdit = ref<boolean>(false)
const defaultFormData = ref<SimEngineBaseInfo>(cloneDeep(DEFAULT_FORM_DATA))

const textMap = computed(() => {
  if (props.dialogType === FormTypeEnum.CREATE) return "上传引擎"
  else if (props.dialogType === FormTypeEnum.EDIT) return "编辑引擎"
  else return "查看引擎"
})
function showDialog() {
  formRef.value?.resetFields()
  fileList.value = []
  isEdit.value = false
  getSimEngineOSOptions()
  detailLoading.value = false
}
function closeDialog() {
  formRef.value?.resetFields()
  emit("closeDialog", undefined)
}
async function getParam(): Promise<FormData> {
  // eslint-disable-next-line no-async-promise-executor
  return new Promise(async (resolve) => {
    const params = new FormData()
    params.append("sim_engine_name", formData.value.sim_engine_name)
    params.append("describe", formData.value.describe)
    params.append("sim_engine_version", formData.value.sim_engine_version)
    params.append("main_file", formData.value.main_file)
    params.append("environment_variables", formData.value.environment_variables)
    params.append("extension_parameters", formData.value.extension_parameters)
    params.append(`sim_engine_os`, (formData.value.sim_engine_os as string[]).join(","))
    if (uploadType.value !== undefined && fileList.value.length > 0) {
      if (uploadType.value === "Folder") {
        // 压缩zip
        const files = fileList.value as File[]
        const fileBlob = await filesToZip(files)
        params.append("sim_engine_files", fileBlob, `${formData.value.sim_engine_files}.zip`)
      }
      if (uploadType.value === "File") {
        const files = fileList.value as UploadUserFile[]
        params.append("sim_engine_files", files[0].raw as Blob)
      }
    }
    resolve(params)
  })
}
function handleConfirm() {
  formRef.value?.validate(async (valid: boolean, fields) => {
    if (!valid) return console.error("表单校验不通过", fields)
    loading.value = true
    const api = props.dialogType == FormTypeEnum.CREATE ? createSimEngineDataApi : updateSimEngineDataApi
    const params: FormData = await getParam()
    api(params)
      .then(() => {
        ElMessage.success("操作成功")
        emit("closeDialog", "refresh")
        loading.value = false
      }).catch(() => {
        loading.value = false
      })
  })
}
function handleCloseTip(done: () => void) {
  if (props.dialogType === FormTypeEnum.VIEW && !isEdit.value) {
    closeDialog()
    done()
    return
  }
  // 校验值是否相同
  if (isEqual(defaultFormData.value, formData.value)) {
    closeDialog()
    done()
    return
  }
  ElMessageBox.confirm("当前编辑未保存，是否确定关闭？").then(() => {
    done()
  })
}
function getSimEngineOSOptions() {
  getSimEngineOSOptionsApi().then(({ data }) => {
    osOptions.value = data.os
  })
}

watch(
  () => [props.id, props.dialogType, props.visible],
  () => {
    dialogVisible.value = props.visible
    if (props.visible) {
      showDialog()
    }
  }
)
watch(
  () => [props.id, props.dialogType],
  () => {
    fileList.value = []
    formData.value = cloneDeep(DEFAULT_FORM_DATA)
    defaultFormData.value = cloneDeep(formData.value)
  }
)
watch(
  () => fileList.value,
  () => {
    if (fileList.value.length > 0) {
      formData.value.sim_engine_files = fileList.value[0].name
    }
  }
)
watch(
  () => fileList.value,
  () => {
    if (uploadType.value != undefined && fileList.value.length > 0) {
      if (uploadType.value == "File") {
        const files = fileList.value as UploadUserFile[]
        formData.value.sim_engine_files = files[0].name
      }
      if (uploadType.value == "Folder") {
        // 文件夹
        const files = fileList.value as File[]
        const relativePath = files[0].webkitRelativePath
        const folderName = relativePath && relativePath.split("/")[0]
        formData.value.sim_engine_files = folderName
      }
    } else {
      formData.value.sim_engine_files = ""
    }
  },
  { deep: true }
)
</script>

<template>
  <el-drawer
    v-model="dialogVisible"
    direction="rtl"
    size="600px"
    @close-auto-focus="closeDialog"
    @close="closeDialog"
    :before-close="handleCloseTip"
    :show-close="false"
  >
    <template #header>
      <div class="drawer-header">
        <h4>{{ textMap }}</h4>
      </div>
    </template>
    <template #default>
      <el-form
        ref="formRef"
        :model="formData"
        :rules="formRules"
        width="600"
        label-width="120px"
        label-position="right"
        :close-on-click-modal="false"
        v-loading="detailLoading"
      >
        <el-form-item label="引擎名称" prop="sim_engine_name">
          <el-input v-model="formData.sim_engine_name" autocomplete="off" placeholder="请输入引擎名称" />
        </el-form-item>
        <el-form-item label="引擎版本" prop="sim_engine_version">
          <el-input
            v-model="formData.sim_engine_version"
            autocomplete="off"
            placeholder="请输入引擎版本"
          />
        </el-form-item>
        <el-form-item label="支持操作系统" prop="sim_engine_os">
          <el-select
            v-model="formData.sim_engine_os"
            multiple
            clearable
            placeholder="请选择操作系统"
          >
            <el-option v-for="item in osOptions" :key="item" :label="item" :value="item" />
          </el-select>
        </el-form-item>
        <el-form-item label="引擎文件" prop="sim_engine_files">
          <UploadFolder
            accept=".zip"
            :file-name="formData.sim_engine_files"
            v-model:upload-type="uploadType"
            v-model:upload-files="fileList"
          />
        </el-form-item>
        <el-form-item label="主文件" prop="main_file">
          <el-input
            v-model="formData.main_file"
            placeholder="请输入主文件名称"
          />
        </el-form-item>
        <el-form-item label="环境变量" prop="environment_variables">
          <el-input
            v-model="formData.environment_variables"
            placeholder="请输入环境变量"
          />
        </el-form-item>
        <el-form-item label="扩展参数" prop="extension_parameters">
          <el-input
            v-model="formData.extension_parameters"
            placeholder="请输入扩展参数"
          />
        </el-form-item>
        <el-form-item label="引擎描述" prop="describe">
          <el-input
            v-model="formData.describe"
            :rows="3"
            type="textarea"
            placeholder="请输入"
            maxlength="600"
          />
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <div class="dialog-footer">
        <el-button plain @click="closeDialog">
          取 消
        </el-button>
        <el-button :loading="loading" type="primary" @click="handleConfirm">
          确 定
        </el-button>
      </div>
    </template>
  </el-drawer>
</template>

<style lang="scss" scoped>
.upload-demo {
  width: 100% !important;
}
:deep(.el-upload.el-upload--text) {
  width: 100% !important;
}
</style>
